LineScanSoftwareTrigger.py

Software Trigger of Line Scan Camera

It shows how to set software trigger of line scan cameras.

1 # -- coding: utf-8 --
2 
3 import sys
4 import platform
5 import os
6 import threading
7 import time
8 
9 
10 # Compatible with different operating systems to load DDL
11 currentsystem = platform.system()
12 if currentsystem == 'Windows':
13  sys.path.append(os.path.join(os.getenv('MVCAM_COMMON_RUNENV'), "Samples", "Python", "MvImport"))
14 else:
15  sys.path.append(os.path.join("..", "..", "MvImport"))
16 from MvCameraControl_class import *
17 
18 # Compatible with input processing of Python 2.X and 3.X
19 if sys.version_info[0] < 3:
20  # Python 2.x
21  input_func = raw_input
22 else:
23  # Python 3.x
24  input_func = input
25 
26 # Decoding Characters
27 def decoding_char(ctypes_char_array):
28  """
29  Safely decode a string from a ctypes character array.
30  Compatible with Python 2.x and 3.x, as well as 32-bit and 64-bit environments.
31  """
32  byte_str = memoryview(ctypes_char_array).tobytes()
33 
34  # Truncate at the first null character
35  null_index = byte_str.find(b'\x00')
36  if null_index != -1:
37  byte_str = byte_str[:null_index]
38 
39  # Attempt to decode using multiple encodings
40  for encoding in ['gbk', 'utf-8', 'latin-1']:
41  try:
42  return byte_str.decode(encoding)
43  except UnicodeDecodeError:
44  continue
45 
46  # If all encodings fail, use a replacement strategy
47  return byte_str.decode('latin-1', errors='replace')
48 
49 
50 g_exit = False
51 fun_ctype = get_platform_functype()
52 
53 stFrameInfo = POINTER(MV_FRAME_OUT_INFO_EX)
54 pData = POINTER(c_ubyte)
55 FrameInfoCallBack = fun_ctype(None, pData, stFrameInfo, c_void_p)
56 
57 def image_callback(pData, pFrameInfo, pUser):
58  stFrameInfo = cast(pFrameInfo, POINTER(MV_FRAME_OUT_INFO_EX)).contents
59  if stFrameInfo:
60  print("get one frame: Width[%d], Height[%d], nFrameNum[%d]" % (stFrameInfo.nWidth, stFrameInfo.nHeight, stFrameInfo.nFrameNum))
61 
62 
63 CALL_BACK_FUN = FrameInfoCallBack(image_callback)
64 
65 
66 # Send software trigger command
67 def software_trigger_thread(cam_ins=0, cmd_value=""):
68  while True:
69  res = cam.MV_CC_SetCommandValue(cmd_value)
70  if res != 0:
71  print("set software trigger command fail[0x%x]" % res)
72  time.sleep(1)
73  if g_exit is True:
74  break
75 
76 
77 def check_feature_node_access(cam_ins, node_name):
78  access_mode = MV_XML_AccessMode()
79  res = cam_ins.MV_XML_GetNodeAccessMode(node_name, access_mode)
80  if res != 0:
81  return False
82  if access_mode == AM_WO or access_mode == AM_RO or access_mode == AM_RW:
83  return True
84  else:
85  return False
86 
87 
88 if __name__ == "__main__":
89 
90  try:
91  # Initialize SDK resources
92  MvCamera.MV_CC_Initialize()
93 
94  SDKVersion = MvCamera.MV_CC_GetSDKVersion()
95  print ("SDKVersion[0x%x]" % SDKVersion)
96 
97  deviceList = MV_CC_DEVICE_INFO_LIST()
98  tlayerType = (MV_GIGE_DEVICE | MV_USB_DEVICE | MV_GENTL_CAMERALINK_DEVICE
99  | MV_GENTL_CXP_DEVICE | MV_GENTL_XOF_DEVICE)
100 
101  # Enumerate devices
102  ret = MvCamera.MV_CC_EnumDevices(tlayerType, deviceList)
103  if ret != 0:
104  print("enum devices fail! ret[0x%x]" % ret)
105  sys.exit()
106 
107  if deviceList.nDeviceNum == 0:
108  print("find no device!")
109  sys.exit()
110 
111  print("Find %d devices!" % deviceList.nDeviceNum)
112 
113  for i in range(0, deviceList.nDeviceNum):
114  mvcc_dev_info = cast(deviceList.pDeviceInfo[i], POINTER(MV_CC_DEVICE_INFO)).contents
115  if mvcc_dev_info.nTLayerType == MV_GIGE_DEVICE or mvcc_dev_info.nTLayerType == MV_GENTL_GIGE_DEVICE:
116  print ("\ngige device: [%d]" % i)
117  strModeName = decoding_char(mvcc_dev_info.SpecialInfo.stGigEInfo.chModelName)
118  print ("device model name: %s" % strModeName)
119  strSerialNumber = decoding_char(mvcc_dev_info.SpecialInfo.stGigEInfo.chSerialNumber)
120  print("device serial number: %s" % strSerialNumber)
121  nip1 = ((mvcc_dev_info.SpecialInfo.stGigEInfo.nCurrentIp & 0xff000000) >> 24)
122  nip2 = ((mvcc_dev_info.SpecialInfo.stGigEInfo.nCurrentIp & 0x00ff0000) >> 16)
123  nip3 = ((mvcc_dev_info.SpecialInfo.stGigEInfo.nCurrentIp & 0x0000ff00) >> 8)
124  nip4 = (mvcc_dev_info.SpecialInfo.stGigEInfo.nCurrentIp & 0x000000ff)
125  print ("current ip: %d.%d.%d.%d\n" % (nip1, nip2, nip3, nip4))
126  elif mvcc_dev_info.nTLayerType == MV_USB_DEVICE:
127  print ("\nu3v device: [%d]" % i)
128  strModeName = decoding_char(mvcc_dev_info.SpecialInfo.stUsb3VInfo.chModelName)
129  print ("device model name: %s" % strModeName)
130 
131  strSerialNumber = decoding_char(mvcc_dev_info.SpecialInfo.stUsb3VInfo.chSerialNumber)
132  print ("device serial number: %s" % strSerialNumber)
133  elif mvcc_dev_info.nTLayerType == MV_GENTL_CAMERALINK_DEVICE:
134  print ("\nCML device: [%d]" % i)
135  strModeName = decoding_char(mvcc_dev_info.SpecialInfo.stCMLInfo.chModelName)
136  print ("device model name: %s" % strModeName)
137 
138  strSerialNumber = decoding_char(mvcc_dev_info.SpecialInfo.stCMLInfo.chSerialNumber)
139  print ("device serial number: %s" % strSerialNumber)
140  elif mvcc_dev_info.nTLayerType == MV_GENTL_CXP_DEVICE:
141  print ("\nCXP device: [%d]" % i)
142  strModeName = decoding_char(mvcc_dev_info.SpecialInfo.stCXPInfo.chModelName)
143  print ("device model name: %s" % strModeName)
144 
145  strSerialNumber = decoding_char(mvcc_dev_info.SpecialInfo.stCXPInfo.chSerialNumber)
146  print ("device serial number: %s" % strSerialNumber)
147  elif mvcc_dev_info.nTLayerType == MV_GENTL_XOF_DEVICE:
148  print ("\nXoF device: [%d]" % i)
149  strModeName = decoding_char(mvcc_dev_info.SpecialInfo.stXoFInfo.chModelName)
150  print ("device model name: %s" % strModeName)
151 
152  strSerialNumber = decoding_char(mvcc_dev_info.SpecialInfo.stXoFInfo.chSerialNumber)
153  print ("device serial number: %s" % strSerialNumber)
154 
155  nConnectionNum = input_func("please input the number of the device to connect:")
156 
157  if int(nConnectionNum) >= deviceList.nDeviceNum:
158  print("input error!")
159  sys.exit()
160 
161  # Create a camera instance
162  cam = MvCamera()
163 
164  # Select a device, and create a handle
165  stDeviceList = cast(deviceList.pDeviceInfo[int(nConnectionNum)], POINTER(MV_CC_DEVICE_INFO)).contents
166 
167  ret = cam.MV_CC_CreateHandle(stDeviceList)
168  if ret != 0:
169  raise Exception("create handle fail! ret[0x%x]" % ret)
170 
171  # Turn on the device
172  ret = cam.MV_CC_OpenDevice(MV_ACCESS_Exclusive, 0)
173  if ret != 0:
174  raise Exception("open device fail! ret[0x%x]" % ret)
175 
176  # Get optimal packet size (only supported by GigE devices)
177  if stDeviceList.nTLayerType == MV_GIGE_DEVICE or stDeviceList.nTLayerType == MV_GENTL_GIGE_DEVICE:
178  nPacketSize = cam.MV_CC_GetOptimalPacketSize()
179  if int(nPacketSize) > 0:
180  ret = cam.MV_CC_SetIntValue("GevSCPSPacketSize", nPacketSize)
181  if ret != 0:
182  print("Warning: Set Packet Size fail! ret[0x%x]" % ret)
183  else:
184  print("Warning: Get Packet Size fail! ret[0x%x]" % nPacketSize)
185 
186  # Pre-set frame trigger of line scan camera
187  ret = cam.MV_CC_SetEnumValueByString("ScanMode", "FrameScan")
188  if ret == 0:
189  print("set frame scan mode")
190 
191  # Check if FrameTriggerControl is readable
192  if check_feature_node_access(cam, "FrameTriggerControl"):
193  # Set trigger mode to on
194  ret = cam.MV_CC_SetBoolValue("FrameTriggerMode", True)
195  if ret != 0:
196  raise Exception("set frame trigger mode on fail! ret[0x%x]" % ret)
197  # Set trigger source to Line0
198  ret = cam.MV_CC_SetEnumValueByString("FrameTriggerSource", "Software")
199  if ret != 0:
200  raise Exception("set trigger source Software fail! ret[0x%x]" % ret)
201 
202  trigger_cmd = "FrameTriggerSoftware"
203  else:
204  # Set trigger selector to FrameBurstStart
205  ret = cam.MV_CC_SetEnumValue("TriggerSelector", 6)
206  if ret != 0:
207  raise Exception("set trigger selector fail! ret[0x%x]" % ret)
208 
209  # Set trigger mode to on
210  ret = cam.MV_CC_SetEnumValue("TriggerMode", 1)
211  if ret != 0:
212  raise Exception("set trigger mode fail! ret[0x%x]" % ret)
213 
214  # Set trigger source to Line0
215  ret = cam.MV_CC_SetEnumValueByString("TriggerSource", "Software")
216  if ret != 0:
217  raise Exception("set trigger source fail! ret[0x%x]" % ret)
218 
219  trigger_cmd = "TriggerSoftware"
220 
221  #Register an image grabbing callback
222  ret = cam.MV_CC_RegisterImageCallBackEx(CALL_BACK_FUN, None)
223  if ret != 0:
224  raise Exception("register image callback fail! ret[0x%x]" % ret)
225 
226  # Start grabbing images
227  ret = cam.MV_CC_StartGrabbing()
228  if ret != 0:
229  raise Exception("start grabbing fail! ret[0x%x]" % ret)
230 
231  try:
232  hThreadHandle = threading.Thread(target=software_trigger_thread, args=(cam, trigger_cmd))
233  hThreadHandle.start()
234  except:
235  print("error: unable to start thread")
236 
237  print ("press Enter key to stop grabbing.")
238  input_func()
239 
240  g_exit = True
241  hThreadHandle.join()
242 
243  # Stop grabbing images
244  ret = cam.MV_CC_StopGrabbing()
245  if ret != 0:
246  raise Exception("stop grabbing fail! ret[0x%x]" % ret)
247 
248  # Turn off the device
249  ret = cam.MV_CC_CloseDevice()
250  if ret != 0:
251  raise Exception("close device fail! ret[0x%x]" % ret)
252 
253  # Destroy the handle
254  cam.MV_CC_DestroyHandle()
255 
256  except Exception as e:
257  print(e)
258  cam.MV_CC_CloseDevice()
259  cam.MV_CC_DestroyHandle()
260  finally:
261  # Release SDK resources
262  MvCamera.MV_CC_Finalize()